package com.example.demo.service;


import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.yeauty.annotation.OnBinary;
import org.yeauty.annotation.OnClose;
import org.yeauty.annotation.OnError;
import org.yeauty.annotation.OnEvent;
import org.yeauty.annotation.OnMessage;
import org.yeauty.annotation.OnOpen;
import org.yeauty.annotation.ServerEndpoint;
import org.yeauty.pojo.ParameterMap;
import org.yeauty.pojo.Session;

import com.google.common.collect.Maps;

import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * @author 88377761
 *
 */
@ServerEndpoint(prefix = "netty-websocket")
@Component
public class WebSocketService {
	private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketService.class);
	public static int COUNT = 0;
	private static Map<String, Session> sessionMap = Maps.newHashMap();
	@OnOpen
	public void onOpen(Session session, HttpHeaders headers, ParameterMap parameterMap) {
		LOGGER.info("new connection");
		String userName = parameterMap.getParameter("userName");
		session.setAttribute("userName", userName);
		sessionMap.put(userName, session);
		LOGGER.info("当前在线人数:{}", ++COUNT);
	}

	@OnClose
	public void onClose(Session session) {
		LOGGER.info("one connection closed");
		LOGGER.info("当前在线人数:{}", --COUNT);
		String userName = session.getAttribute("userName");
		sessionMap.remove(userName);
	}

	@OnError
	public void onError(Session session, Throwable throwable) {
		LOGGER.error("webSocket error", throwable);
	}

	@OnMessage
	public void onMessage(Session session, String message) {
		for (Session sessionOld : sessionMap.values())
			sessionOld.sendText(message);
	}

	@OnBinary
	public void onBinary(Session session, byte[] bytes) {
		session.sendBinary(bytes);
	}

	@OnEvent
	public void onEvent(Session session, Object evt) {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
			switch (idleStateEvent.state()) {
			case READER_IDLE:
				LOGGER.info("read idle");
				break;
			case WRITER_IDLE:
				LOGGER.info("write idle");
				break;
			case ALL_IDLE:
				LOGGER.info("all idle");
				break;
			default:
				break;
			}
		}
	}

}
